package luz.javaproxy.proxy;

import luz.javaproxy.common.Tuple;

import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;

class HttpProxyExecutionHandler implements HttpRequestExecutionHandler {
    private final static String REQUEST_SENT       = "request-sent";
    private final static String RESPONSE_RECEIVED  = "response-received";
    private final static String CONTAINER          = "container";

    public HttpProxyExecutionHandler() {
        super();
    }

    @SuppressWarnings("unchecked")
	public void initalizeContext(final HttpContext context, final Object attachment) {
    	Tuple<Object, Object> container=(Tuple<Object, Object>)attachment;
    	context.setAttribute(CONTAINER, container);
        context.setAttribute(ExecutionContext.HTTP_REQUEST, container.getSecond());	//Add request to context
    	container.setSecond(null);	//remove Request.
    }

    public HttpRequest submitRequest(final HttpContext context) {
        if (context.getAttribute(REQUEST_SENT) == null) {
            context.setAttribute(REQUEST_SENT, Boolean.TRUE);
            return (HttpRequest)context.getAttribute(ExecutionContext.HTTP_REQUEST);
        } else {
            return null; // No new request to submit
        }
    }
    
    @SuppressWarnings("unchecked")
	public void handleResponse(final HttpResponse response, final HttpContext context) {
        context.setAttribute(RESPONSE_RECEIVED, Boolean.TRUE);
        // Signal completion of the request execution
        Tuple<Object, Object> container = (Tuple<Object, Object>)context.getAttribute(CONTAINER);
        container.setSecond(response);	//Insert response
        Object trigger=container.getFirst();
        synchronized (trigger) {trigger.notify(); }
    }
    
    public void finalizeContext(final HttpContext context) {
    	context.setAttribute(ExecutionContext.HTTP_REQUEST, null);	//CleanUP
    }
}